import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;


 //游戏核心逻辑类，处理游戏规则和算法

public class GameLogic {
    private final GameState state;

    public GameLogic(GameState state) {
        this.state = state;
    }

    public void generateMap() {
        List<Integer> numbers = new ArrayList<>();
        Random random = new Random();

        int totalPairs = (GameState.ROWS * GameState.COLS) / 2;
        int realKinds = Math.min(GameState.KIND_COUNT, totalPairs);
        for (int i = 0; i < totalPairs; i++) {
            int type = random.nextInt(realKinds) + 1;
            numbers.add(type);
            numbers.add(type);
        }
        Collections.shuffle(numbers);

        int index = 0;
        for (int row = 0; row < GameState.ROWS; row++) {
            for (int col = 0; col < GameState.COLS; col++) {
                state.map[row][col] = numbers.get(index++);
            }
        }
    }

    public boolean canLink(int rowA, int colA, int rowB, int colB) {
        // 1. 直接相同（同一个单元格，理论上不会触发）
        if (rowA == rowB && colA == colB) return false;

        // 2. 图片类型不同，无法消除
        if (state.map[rowA][colA] != state.map[rowB][colB]) return false;

        // 3. 直线连通判断（行相同 或 列相同）
        if (rowA == rowB) {
            return isRowClear(rowA, colA, colB);
        }
        if (colA == colB) {
            return isColumnClear(colA, rowA, rowB);
        }

        // 4. 拐角连通（Z 字形，最多两个拐点）
        return isZigzagLink(rowA, colA, rowB, colB);
    }

    private boolean isRowClear(int row, int col1, int col2) {
        if (col1 == col2) return true;
        int minCol = Math.min(col1, col2);
        int maxCol = Math.max(col1, col2);
        for (int col = minCol + 1; col < maxCol; col++) {
            if (state.map[row][col] != 0) return false;
        }
        return true;
    }

    private boolean isColumnClear(int col, int row1, int row2) {
        if (row1 == row2) return true;
        int minRow = Math.min(row1, row2);
        int maxRow = Math.max(row1, row2);
        for (int row = minRow + 1; row < maxRow; row++) {
            if (state.map[row][col] != 0) return false;
        }
        return true;
    }

    private boolean isZigzagLink(int rowA, int colA, int rowB, int colB) {
        if (state.map[rowA][colB] == 0 && isColumnClear(colB, rowA, rowB) && isRowClear(rowA, colA, colB)) {
            return true;
        }
        if (state.map[rowB][colA] == 0 && isColumnClear(colA, rowA, rowB) && isRowClear(rowB, colA, colB)) {
            return true;
        }
        return false;
    }

    public List<int[]> findAllRemovablePairs() {
        List<int[]> pairs = new ArrayList<>();

        for (int row1 = 0; row1 < GameState.ROWS; row1++) {
            for (int col1 = 0; col1 < GameState.COLS; col1++) {
                if (state.map[row1][col1] == 0) continue;

                for (int row2 = 0; row2 < GameState.ROWS; row2++) {
                    for (int col2 = 0; col2 < GameState.COLS; col2++) {
                        if ((row1 == row2 && col1 == col2) || state.map[row2][col2] == 0) continue;

                        if (state.map[row1][col1] == state.map[row2][col2] && canLink(row1, col1, row2, col2)) {
                            pairs.add(new int[]{row1, col1, row2, col2});
                        }
                    }
                }
            }
        }

        return pairs;
    }

    public boolean checkWin() {
        for (int row = 0; row < GameState.ROWS; row++) {
            for (int col = 0; col < GameState.COLS; col++) {
                if (state.map[row][col] != 0) {
                    return false;
                }
            }
        }
        state.gameOver = true;
        return true;
    }
}
